package org.assistant.common.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.assistant.common.exception.ImplementNotFoundException;

public class ClassUtils {
	/**
	 * 获取类加载器
	 * 
	 * @return
	 */
	public static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			cl = Thread.currentThread().getContextClassLoader();
		} catch (Throwable ex) {
			// Cannot access thread context ClassLoader - falling back to system
			// class loader...
		}
		if (cl == null) {
			// No thread context class loader -> use class loader of this class.
			cl = ClassUtils.class.getClassLoader();
		}
		return cl;
	}

	static class ConfigUtils {
		private static Properties config = null;

		private static Properties loadConfig() {
			if (config == null) {
				config = new Properties();
				InputStream in = getDefaultClassLoader().getResourceAsStream(
					"/interface.cfg");
				try {
					config.load(in);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return config;
		}
	}

	/**
	 * 根据类名获取该类的一个实例
	 * 
	 * @param className
	 * @return
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static Object getInstance(String className)
			throws InstantiationException, IllegalAccessException,
			ClassNotFoundException {
		return getDefaultClassLoader().loadClass(className).newInstance();
	}

	/**
	 * 根据接口全名获取该接口的默认实现(如果没有显式地配置该接口的实现类)；<br>
	 * （默认实现是指实现接口的类的命名满足以下规则的实现：InterfaceName+Impl）<br>
	 * 如果配置了该接口的实现类，则返回该实现类的实例
	 * 
	 * @param interfaceName
	 * @return
	 * @throws ImplementNotFoundException
	 */
	public static Object getInterfaceImplement(String interfaceName)
			throws ImplementNotFoundException {
		Object result = null;

		Properties cfg = ConfigUtils.loadConfig();
		String implName = (String) cfg.get(interfaceName);
		try {
			if (implName != null && !"".equals(implName)) {
				result = getDefaultClassLoader()
					.loadClass(implName).newInstance();
			} else {
				result = getDefaultClassLoader().loadClass(
					interfaceName + "Impl").newInstance();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ImplementNotFoundException(interfaceName, e.getMessage());
		}

		return result;
	}

	/**
	 * 根据接口类获取该接口的默认实现(如果没有显式地配置该接口的实现类)；<br>
	 * （默认实现是指实现接口的类的命名满足以下规则的实现：InterfaceName+Impl）<br>
	 * 如果配置了该接口的实现类，则返回该实现类的实例
	 * 
	 * @param interfaceClass
	 * @return
	 * @throws ImplementNotFoundException
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getInterfaceImplement(Class<?> interfaceClass)
			throws ImplementNotFoundException {
		Object result = null;

		Properties cfg = ConfigUtils.loadConfig();
		String implName = (String) cfg.get(interfaceClass.getName());
		try {
			if (implName != null && !"".equals(implName)) {
				result = getDefaultClassLoader()
					.loadClass(implName).newInstance();
			} else {
				result = getDefaultClassLoader().loadClass(
					interfaceClass.getName() + "Impl").newInstance();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ImplementNotFoundException(interfaceClass, e.getMessage());
		}

		return (T) result;
	}
}
